
import multiprocessing

class SuperProc(multiprocessing.Process):
    def __init__(self, pipe, pipeHelp, index):
        super(SuperProc, self).__init__()
        self.p = pipe
        self.pH = pipeHelp
    def __del__(self):
        self.p.close()
        self.pH.close()
        
    def automatic_generation(self, name, gen_fn, *arg):
        setattr(self, name, gen_fn(*arg))
    def automatic_execution(self, name, dowhat, *arg):
        return  getattr(getattr(self, name), dowhat)(*arg)
        
    def add_targets(self, new_target_args):
        for new_target_arg in new_target_args:
            name, gen_fn, arg = new_target_arg
            if arg is None:              self.automatic_generation(name, gen_fn)
            elif isinstance(arg, tuple): self.automatic_generation(name, gen_fn, *arg)
            else:                        self.automatic_generation(name, gen_fn, arg)

    def execute_target(self, recv_args):
        res_list = [None] * len(recv_args)
        for i, recv_arg in enumerate(recv_args):
            name, dowhat, arg = recv_arg
            if arg is None:              res = self.automatic_execution(name, dowhat)
            elif isinstance(arg, tuple): res = self.automatic_execution(name, dowhat, *arg)
            else:                        res = self.automatic_execution(name, dowhat, arg)
            res_list[i] = res
        return res_list

    def run(self):
        while True:
            recv_args = self.p.recv()
            if not isinstance(recv_args, list): # not list object, switch to helper channel
                if recv_args == 0: self.add_targets(self.pH.recv())
                elif recv_args == -1: break # terminate
                else: assert False
                continue
            result = self.execute_target(recv_args)
            self.p.send(result)
        self.__del__()